﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using VSIXUtilities.DataObjects.Enums;

namespace VSIXUtilities.EventsListeners
{
	public class VsUpdateSolutionEvents2 : IVsUpdateSolutionEvents2, IDisposable
	{
		IVsSolutionBuildManager2 sbm;
		private uint pdwCookie;
		private bool IsDisposed;
		private static volatile object Mutex = new object();
		public delegate void UpdateProjectCfgDoneHandler(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, _SLNUPDACTION dwAction, int fSuccess, int fCancel);
		public delegate void UpdateSolutionDoneHandler(int fSucceeded, int fModified, int fCancelCommand);
		public event UpdateProjectCfgDoneHandler UpdateProjectCfgDone;
		public event UpdateSolutionDoneHandler UpdateSolutionDone;

		public VsUpdateSolutionEvents2()
		{
			sbm = ServiceProvider.GlobalProvider.GetService(typeof(SVsSolutionBuildManager)) as IVsSolutionBuildManager2;
			if(sbm != null)
			{
				sbm.AdviseUpdateSolutionEvents(this, out pdwCookie);
			}
		}

		#region IVsUpdateSolutionEvents2 Members

		public int OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy)
		{
			return VSConstants.E_NOTIMPL;
		}

		public int UpdateProjectCfg_Begin(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, ref int pfCancel)
		{
			return VSConstants.E_NOTIMPL;
		}

		public int UpdateProjectCfg_Done(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, int fSuccess, int fCancel)
		{
			if(UpdateProjectCfgDone != null)
			{
				UpdateProjectCfgDone(pHierProj, pCfgProj, pCfgSln, (_SLNUPDACTION)Enum.Parse(typeof(_SLNUPDACTION), dwAction.ToString()), fSuccess, fCancel);
			}
			return VSConstants.E_NOTIMPL;
		}

		public int UpdateSolution_Begin(ref int pfCancelUpdate)
		{
			return VSConstants.E_NOTIMPL;
		}

		public int UpdateSolution_Cancel()
		{
			return VSConstants.E_NOTIMPL;
		}

		public int UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand)
		{
			if(UpdateSolutionDone != null)
			{
				UpdateSolutionDone(fSucceeded, fModified, fCancelCommand);
			}
			return VSConstants.E_NOTIMPL;
		}

		public int UpdateSolution_StartUpdate(ref int pfCancelUpdate)
		{
			return VSConstants.E_NOTIMPL;
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		#endregion

		protected virtual void Dispose(bool disposing)
		{
			if(!IsDisposed)
			{
				lock(Mutex)
				{
					if(sbm != null && pdwCookie != (uint)Constants.VSCOOKIE_NIL)
					{
						sbm.UnadviseUpdateSolutionEvents(pdwCookie);
						pdwCookie = (uint)Constants.VSCOOKIE_NIL;
					}
					IsDisposed = true;
				}
			}
		}

	}
}
